package com.bookocean.infrastructure.persistence.repository;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bookocean.application.exception.BusinessException;
import com.bookocean.application.exception.WeChatErrorCodeEnum;
import com.bookocean.controller.dto.FavoriteDto;
import com.bookocean.controller.dto.PageResultDto;
import com.bookocean.domain.repository.BookFavoriteRepository;
import com.bookocean.infrastructure.persistence.mapper.BookFavoriteMapper;
import com.bookocean.infrastructure.persistence.mapper.BookQuoteMapper;
import com.bookocean.infrastructure.persistence.mapper.NovelMapper;
import com.bookocean.infrastructure.persistence.mapper.BookMapper;
import com.bookocean.infrastructure.persistence.mapper.UserInfoMapper;
import com.bookocean.infrastructure.persistence.po.BookFavoritePO;
import com.bookocean.infrastructure.persistence.po.BookQuotePO;
import com.bookocean.infrastructure.persistence.po.NovelPO;
import com.bookocean.infrastructure.persistence.po.BookPO;
import com.bookocean.infrastructure.persistence.po.UserInfoPO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * 书摘收藏仓储实现类
 *
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class BookFavoriteRepositoryImpl implements BookFavoriteRepository {

    private final BookFavoriteMapper bookFavoriteMapper;
    private final BookQuoteMapper bookQuoteMapper;
    private final NovelMapper novelMapper;
    private final BookMapper bookMapper;
    private final UserInfoMapper userInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createFavorite(Long quoteId, Long userId) {
        try {
            // 创建收藏记录（书摘类型）
            BookFavoritePO bookFavoritePO = new BookFavoritePO();
            bookFavoritePO.setTargetType(1); // 书摘类型
            bookFavoritePO.setTargetId(quoteId);
            bookFavoritePO.setUserId(userId);
            bookFavoritePO.setCreatedAt(LocalDateTime.now());

            int result = bookFavoriteMapper.insert(bookFavoritePO);
            if (result > 0) {
                log.info("创建收藏成功: quoteId={}, userId={}", quoteId, userId);
            } else {
                log.error("创建收藏失败，数据库插入返回0: quoteId={}, userId={}", quoteId, userId);
                throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
            }
        } catch (DuplicateKeyException e) {
            // 处理重复收藏（由于数据库唯一约束）
            log.warn("重复收藏，忽略操作: quoteId={}, userId={}", quoteId, userId);
        } catch (Exception e) {
            log.error("创建收藏失败: quoteId={}, userId={}, 错误: {}", quoteId, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByQuoteIdAndUserId(Long quoteId, Long userId) {
        // 参数校验
        if (ObjectUtil.isEmpty(quoteId) || ObjectUtil.isEmpty(userId)) {
            log.warn("删除收藏失败，书摘ID或用户ID不能为空: quoteId={}, userId={}", quoteId, userId);
            throw new BusinessException(WeChatErrorCodeEnum.PARAM_ERROR);
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, 1) // 书摘类型
                    .eq(BookFavoritePO::getTargetId, quoteId)
                    .eq(BookFavoritePO::getUserId, userId);

            int result = bookFavoriteMapper.delete(queryWrapper);
            if (result > 0) {
                log.info("删除收藏成功: quoteId={}, userId={}", quoteId, userId);
            } else {
                log.warn("删除收藏失败，未找到对应记录: quoteId={}, userId={}", quoteId, userId);
            }
        } catch (Exception e) {
            log.error("删除收藏失败: quoteId={}, userId={}, 错误: {}", quoteId, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    public boolean existsByQuoteIdAndUserId(Long quoteId, Long userId) {
        // 参数校验
        if (ObjectUtil.isEmpty(quoteId) || ObjectUtil.isEmpty(userId)) {
            log.warn("检查收藏状态失败，书摘ID或用户ID不能为空: quoteId={}, userId={}", quoteId, userId);
            return false;
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, 1) // 书摘类型
                    .eq(BookFavoritePO::getTargetId, quoteId)
                    .eq(BookFavoritePO::getUserId, userId);

            Long count = bookFavoriteMapper.selectCount(queryWrapper);
            boolean exists = count != null && count > 0;
            log.debug("检查收藏状态: quoteId={}, userId={}, exists={}", quoteId, userId, exists);
            return exists;
        } catch (Exception e) {
            log.error("检查收藏状态失败: quoteId={}, userId={}, 错误: {}", quoteId, userId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    public Integer getFavoriteCount(Long quoteId) {
        // 参数校验
        if (ObjectUtil.isEmpty(quoteId)) {
            log.warn("获取收藏数量失败，书摘ID不能为空: quoteId={}", quoteId);
            return 0;
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, 1) // 书摘类型
                    .eq(BookFavoritePO::getTargetId, quoteId);

            Long count = bookFavoriteMapper.selectCount(queryWrapper);
            Integer favoriteCount = count != null ? count.intValue() : 0;
            log.debug("获取收藏数量: quoteId={}, count={}", quoteId, favoriteCount);
            return favoriteCount;
        } catch (Exception e) {
            log.error("获取收藏数量失败: quoteId={}, 错误: {}", quoteId, e.getMessage(), e);
            return 0;
        }
    }

    // ========== 通用互动方法实现 ==========

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void favorite(Long targetId, Integer targetType, Long userId) {
        try {
            BookFavoritePO bookFavoritePO = new BookFavoritePO();
            bookFavoritePO.setTargetType(targetType);
            bookFavoritePO.setTargetId(targetId);
            bookFavoritePO.setUserId(userId);
            bookFavoritePO.setCreatedAt(LocalDateTime.now());

            int result = bookFavoriteMapper.insert(bookFavoritePO);
            if (result > 0) {
                log.info("创建收藏成功: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
            } else {
                log.error("创建收藏失败，数据库插入返回0: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
                throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
            }
        } catch (DuplicateKeyException e) {
            log.warn("重复收藏，忽略操作: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
        } catch (Exception e) {
            log.error("创建收藏失败: targetId={}, targetType={}, userId={}, 错误: {}", targetId, targetType, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unfavorite(Long targetId, Integer targetType, Long userId) {
        if (ObjectUtil.isEmpty(targetId) || ObjectUtil.isEmpty(targetType) || ObjectUtil.isEmpty(userId)) {
            log.warn("删除收藏失败，参数不能为空: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
            throw new BusinessException(WeChatErrorCodeEnum.PARAM_ERROR);
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, targetType)
                    .eq(BookFavoritePO::getTargetId, targetId)
                    .eq(BookFavoritePO::getUserId, userId);

            int result = bookFavoriteMapper.delete(queryWrapper);
            if (result > 0) {
                log.info("删除收藏成功: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
            } else {
                log.warn("删除收藏失败，未找到对应记录: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
            }
        } catch (Exception e) {
            log.error("删除收藏失败: targetId={}, targetType={}, userId={}, 错误: {}", targetId, targetType, userId, e.getMessage(), e);
            throw new BusinessException(WeChatErrorCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    public boolean isFavoritedByUser(Long targetId, Integer targetType, Long userId) {
        if (ObjectUtil.isEmpty(targetId) || ObjectUtil.isEmpty(targetType) || ObjectUtil.isEmpty(userId)) {
            log.warn("检查收藏状态失败，参数不能为空: targetId={}, targetType={}, userId={}", targetId, targetType, userId);
            return false;
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, targetType)
                    .eq(BookFavoritePO::getTargetId, targetId)
                    .eq(BookFavoritePO::getUserId, userId);

            Long count = bookFavoriteMapper.selectCount(queryWrapper);
            boolean exists = count != null && count > 0;
            log.debug("检查收藏状态: targetId={}, targetType={}, userId={}, exists={}", targetId, targetType, userId, exists);
            return exists;
        } catch (Exception e) {
            log.error("检查收藏状态失败: targetId={}, targetType={}, userId={}, 错误: {}", targetId, targetType, userId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    public Integer countByTarget(Long targetId, Integer targetType) {
        if (ObjectUtil.isEmpty(targetId) || ObjectUtil.isEmpty(targetType)) {
            log.warn("获取收藏数量失败，参数不能为空: targetId={}, targetType={}", targetId, targetType);
            return 0;
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getTargetType, targetType)
                    .eq(BookFavoritePO::getTargetId, targetId);

            Long count = bookFavoriteMapper.selectCount(queryWrapper);
            Integer favoriteCount = count != null ? count.intValue() : 0;
            log.debug("获取收藏数量: targetId={}, targetType={}, count={}", targetId, targetType, favoriteCount);
            return favoriteCount;
        } catch (Exception e) {
            log.error("获取收藏数量失败: targetId={}, targetType={}, 错误: {}", targetId, targetType, e.getMessage(), e);
            return 0;
        }
    }

    @Override
    public PageResultDto<FavoriteDto> getUserFavorites(Long userId, Integer targetType, Integer page, Integer pageSize) {
        if (ObjectUtil.isEmpty(userId)) {
            log.warn("获取用户收藏列表失败，用户ID不能为空: userId={}", userId);
            return new PageResultDto<FavoriteDto>(java.util.Collections.emptyList(), 0L, page, pageSize);
        }

        try {
            LambdaQueryWrapper<BookFavoritePO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BookFavoritePO::getUserId, userId);

            // 如果指定了目标类型，则按类型过滤
            if (ObjectUtil.isNotEmpty(targetType)) {
                queryWrapper.eq(BookFavoritePO::getTargetType, targetType);
            }

            // 按创建时间倒序排列
            queryWrapper.orderByDesc(BookFavoritePO::getCreatedAt);

            // 分页查询
            com.baomidou.mybatisplus.extension.plugins.pagination.Page<BookFavoritePO> pageParam =
                    new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, pageSize);
            com.baomidou.mybatisplus.extension.plugins.pagination.Page<BookFavoritePO> result =
                    bookFavoriteMapper.selectPage(pageParam, queryWrapper);

            // 转换为DTO列表，过滤掉null值（不存在的书摘收藏）
            java.util.List<FavoriteDto> favoriteDtos = result.getRecords().stream()
                    .map(this::convertToFavoriteDto)
                    .filter(java.util.Objects::nonNull)
                    .collect(java.util.stream.Collectors.toList());

            log.info("获取用户收藏列表成功: userId={}, targetType={}, total={}, page={}, pageSize={}",
                    userId, targetType, result.getTotal(), page, pageSize);

            return new PageResultDto<FavoriteDto>(
                    favoriteDtos, result.getTotal(), page, pageSize);
        } catch (Exception e) {
            log.error("获取用户收藏列表失败: userId={}, targetType={}, 错误: {}", userId, targetType, e.getMessage(), e);
            return new PageResultDto<FavoriteDto>(java.util.Collections.emptyList(), 0L, page, pageSize);
        }
    }

    /**
     * 转换BookFavoritePO为FavoriteDto
     */
    private FavoriteDto convertToFavoriteDto(BookFavoritePO po) {
        FavoriteDto dto = new FavoriteDto();
        dto.setFavoriteId(po.getFavoriteId());
        dto.setTargetId(po.getTargetId());
        dto.setTargetType(po.getTargetType());
        dto.setCreatedAt(po.getCreatedAt());

        // 设置收藏时间（格式化）
        dto.setFavoriteTime(po.getCreatedAt() != null ?
                po.getCreatedAt().toString().substring(0, 10) : "");

        // 只处理书摘类型的收藏，且书摘必须存在
        try {
            if (po.getTargetType() == 1) {
                // 书摘类型 - 查询书摘信息
                BookQuotePO bookQuote = bookQuoteMapper.selectById(po.getTargetId());
                if (bookQuote != null) {
                    // 设置书摘信息
                    dto.setTargetTitle("书摘");
                    dto.setTargetContent(bookQuote.getContent());
                    dto.setTargetImageUrl(bookQuote.getImageUrl());
                    dto.setCreatorId(bookQuote.getUserId());

                    // 查询关联的书籍信息
                    if (bookQuote.getBookId() != null) {
                        BookPO book = bookMapper.selectById(bookQuote.getBookId());
                        if (book != null) {
                            dto.setBookId(book.getBookId());
                            dto.setBookTitle(book.getTitle());
                            dto.setBookAuthor(book.getAuthor());
                            dto.setBookCoverUrl(book.getCoverUrl());
                        }
                    }

                    // 查询创建者信息
                    if (bookQuote.getUserId() != null) {
                        UserInfoPO creator = userInfoMapper.selectById(bookQuote.getUserId());
                        if (creator != null) {
                            dto.setCreatorNickname(creator.getNickName());
                            dto.setCreatorAvatarUrl(creator.getAvatarUrl());
                        }
                    }

                    // 设置默认统计信息（后续可以查询真实的统计数据）
                    dto.setLikeCount(0);
                    dto.setCommentCount(0);
                    dto.setFavoriteCount(1);
                } else {
                    // 书摘不存在，返回null表示跳过此收藏
                    log.warn("书摘不存在，跳过收藏: targetId={}", po.getTargetId());
                    return null;
                }
            } else {
                // 非书摘类型，返回null表示跳过
                log.warn("跳过非书摘类型的收藏: targetType={}, targetId={}", 
                        po.getTargetType(), po.getTargetId());
                return null;
            }
        } catch (Exception e) {
            log.warn("查询收藏目标详情失败: targetType={}, targetId={}, error={}",
                    po.getTargetType(), po.getTargetId(), e.getMessage());
            // 查询失败，返回null表示跳过此收藏
            return null;
        }

        return dto;
    }
}
